﻿using System;
using System.Collections;
using Eneta.Portal.Common;
using Microsoft.SharePoint;
using System.Web;
using Eneta.Portal.Common.Definitions;

namespace Eneta.Portal.Authentication.Live
{
    public class BlogUserProfile
    {
        protected string strId;
        protected string strPicture;
        protected string strDepartment;
        protected string strJobTitle;
        protected string strSipAddress;
        protected DateTime dateCreated;
        protected DateTime dateLastLogin;
        protected DateTime dateLockedOn;

        static protected object cache;

        public string DisplayName { get; set; }
        public string Email { get; set; }
        public int ItemId { get; internal set; }

        public string Id
        {
            get
            {
                return strId;
            }
        }

        public string AboutMe { get; set; }

        public string Picture
        {
            get
            {
                return strPicture;
            }
            set
            {
                if (Uri.IsWellFormedUriString(value, UriKind.RelativeOrAbsolute))
                {
                    strPicture = value;
                }
            }
        }

        public string Department
        {
            get
            {
                return strDepartment;
            }
            set
            {
                strDepartment = value;
            }
        }

        public string JobTitle
        {
            get
            {
                return strJobTitle;
            }
            set
            {
                strJobTitle = value;
            }
        }

        public string SipAddress
        {
            get
            {
                return strSipAddress;
            }
            set
            {
                strSipAddress = value;
            }
        }

        public bool Approved { get; set; }
        public bool Locked { get; set; }

        public DateTime Created
        {
            get
            {
                return dateCreated;
            }
        }

        public DateTime LastLogin
        {
            get
            {
                return dateLastLogin;
            }
            set
            {
                dateLastLogin = value;
            }
        }

        public DateTime LockedOn
        {
            get
            {
                return dateLockedOn;
            }
            set
            {
                dateLockedOn = value;
            }
        }

        public BlogUserProfile(SPListItem user)
        {
            //strId = GetListItemString(_user, "Title");
            strId = GetListItemString(user, UserProfileFields.SysId);
            //strDisplayName = GetListItemString(_user, "DisplayName");
            DisplayName = GetListItemString(user, UserProfileFields.Title);
            //strDepartment = GetListItemString(user, UserProfileFields.de);
            Email = GetListItemString(user, UserProfileFields.Email);
            AboutMe = GetListItemString(user, UserProfileFields.AboutMe);
            //strPicture = GetListItemString(user, "Picture");
            strJobTitle = GetListItemString(user, UserProfileFields.JobTitle);
            //strSipAddress = GetListItemString(user, "SipAddress");
            ItemId = user.ID;
            Locked = GetListItemBool(user, UserProfileFields.Locked);
            Approved = true;

            dateCreated = DateTime.Now;
            dateLastLogin = DateTime.Now;
            dateLockedOn = DateTime.MaxValue;
        }

        static public BlogUserProfile GetUser(string id)
        {
            BlogUserProfile ret = null;

            SPSecurity.RunWithElevatedPrivileges(
                delegate
                {
                    using (var elevSite = new SPSite(AuthConfig.ProfileSiteUrl))
                    {
                        using (var elevWeb = elevSite.OpenWeb())
                        {
                            var list = elevWeb.GetList(Lists.ProfileList);
                            var q = new SPQuery();
                            if (id.IndexOf("@") != -1)
                            {                                
                                q.Query = string.Format("<Where><Eq><FieldRef Name='{0}'/><Value Type='Text'>{1}</Value></Eq></Where>", list.Fields[UserProfileFields.Email].InternalName, id);
                            }
                            else
                            {
                                q.Query = string.Format("<Where><Eq><FieldRef Name='{0}'/><Value Type='Text'>{1}</Value></Eq></Where>", list.Fields[UserProfileFields.SysId].InternalName, id);
                            }
                            var items = list.GetItems(q);
                            if (items.Count != 0)
                            {
                                //                                cache = new BlogUserProfile(items[0]);
                                ret = new BlogUserProfile(items[0]);
                            }
                        }
                    }
                }
            );

            /*if (cache != null)
            {
                ret = (BlogUserProfile)cache;
                cache = null;
            }*/

            return ret;
        }

        static public BlogUserProfile[] GetUsersByTag(string id, string tag)
        {
            ArrayList ret = null;

            SPSecurity.RunWithElevatedPrivileges(
                delegate
                {
                    var array = new ArrayList();
                    using (var elevSite = new SPSite(AuthConfig.ProfileSiteUrl))
                    {
                        using (var elevWeb = elevSite.OpenWeb())
                        {
                            var list = elevWeb.GetList(Lists.ProfileList);
                            var q = new SPQuery();
                            q.Query = string.Format("<Where><Contains><FieldRef ID='{0}'/><Value Type='Text'>{1}</Value></Contains></Where>", tag, id);
                            Logger.LogInfo("User search: " + q.Query);
                            var items = list.GetItems(q);

                            Logger.LogInfo("User searh: " + items.Count);
                            if (items.Count != 0)
                            {
                                foreach (SPListItem item in items)
                                {
                                    array.Add(new BlogUserProfile(item));
                                }
                            }
                        }
                    }
                    //cache = array;
                    ret = array;
                }
            );

            //if (cache != null)
            //{
            //    ret = (ArrayList)cache;
            //    cache = null;
            //}

            return (BlogUserProfile[])ret.ToArray(typeof(BlogUserProfile));
        }

        static public BlogUserProfile[] GetAllUsers()
        {
            ArrayList ret = null;

            SPSecurity.RunWithElevatedPrivileges(
                delegate
                {
                    var array = new ArrayList();
                    using (var elevSite = new SPSite(AuthConfig.ProfileSiteUrl))
                    {
                        using (var elevWeb = elevSite.OpenWeb())
                        {
                            var list = elevWeb.GetList(Lists.ProfileList);
                            if (list.Items.Count != 0)
                            {
                                foreach (SPListItem item in list.Items)
                                {
                                    array.Add(new BlogUserProfile(item));
                                }
                            }
                        }
                    }
                    //cache = array;
                    ret = array;
                }
            );

            //if (cache != null)
            //{
            //    ret = (ArrayList)cache;
            //    cache = null;
            //}

            return (BlogUserProfile[])ret.ToArray(typeof(BlogUserProfile));
        }
        //C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin
        static public bool CreateUser(string id, string email)
        {
            var ret = false;

            SPSecurity.RunWithElevatedPrivileges(
                delegate
                {
                    using (var elevSite = new SPSite(AuthConfig.ProfileSiteUrl))
                    {
                        using (var elevWeb = elevSite.OpenWeb())
                        {
                            elevSite.AllowUnsafeUpdates = true;
                            elevWeb.AllowUnsafeUpdates = true;
                            var list = elevWeb.GetList(Lists.ProfileList);
                            var q = new SPQuery();
                            q.Query = string.Format("<Where><Eq><FieldRef Name='{0}'/><Value Type='Text'>{1}</Value></Eq></Where>", list.Fields[UserProfileFields.SysId].InternalName, id);
                            var items = list.GetItems(q);
                            if (items.Count == 0)
                            {                                
                                var item = list.Items.Add();
                                item[UserProfileFields.Email] = email;
                                item[UserProfileFields.SysId] = id;
                                item[UserProfileFields.Locked] = false;
                                item.Update();
                                //cache = true;
                            }
                        }
                    }
                }
            );

            //if (cache != null)
            //{
            //    ret = (bool)cache;
            //    cache = null;
            //}

            return ret;
        }

        public void Update()
        {
            SPSecurity.RunWithElevatedPrivileges(
                delegate
                {
                    using (var elevSite = new SPSite(AuthConfig.ProfileSiteUrl))
                    {
                        using (var elevWeb = elevSite.OpenWeb())
                        {
                            elevSite.AllowUnsafeUpdates = true;
                            elevWeb.AllowUnsafeUpdates = true;
                            var list = elevWeb.GetList(Lists.ProfileList);
                            var q = new SPQuery();
                            q.Query = string.Format("<Where><Eq><FieldRef Name='{0}'/><Value Type='Text'>{1}</Value></Eq></Where>", list.Fields[UserProfileFields.SysId].InternalName, Id);
                            var items = list.GetItems(q);
                            if (items.Count != 0)
                            {
                                var item = items[0];
                                try
                                {
                                    item[UserProfileFields.Email] = Email;
                                }
                                catch
                                { }
                                try
                                {
                                    item[UserProfileFields.Title] = DisplayName;
                                }
                                catch
                                { }
                                try
                                {
                                    //item["Department"] = Department;
                                }
                                catch
                                { }
                                try
                                {
                                    item[UserProfileFields.AboutMe] = AboutMe;
                                }
                                catch
                                { }
                                try
                                {
                                    //item["Picture"] = Picture;
                                }
                                catch
                                { }
                                try
                                {
                                    item[UserProfileFields.JobTitle] = JobTitle;
                                }
                                catch
                                { }
                                try
                                {
                                    //item["SipAddress"] = SipAddress;
                                }
                                catch
                                { }
                                item[UserProfileFields.ShowFirstName] = true;
                                item[UserProfileFields.ShowLastName] = true;
                                item[UserProfileFields.SendEventsInfo] = true;
                                item[UserProfileFields.SendMsInfo] = true;
                                item.Update();
                            }
                        }
                    }
                }
            );

        }

        private string GetListItemString(SPListItem item, string column)
        {
            var ret = "";
            var data = GetListItemData(item, column);

            if (data != null)
            {
                ret = data.ToString();
            }

            return ret;
        }

        private string GetListItemString(SPListItem item, Guid guid)
        {
            var ret = "";
            var data = GetListItemData(item, guid);

            if (data != null)
            {
                ret = data.ToString();
            }

            return ret;
        }

        private bool GetListItemBool(SPListItem item, string column)
        {
            bool ret = false;
            object data = GetListItemData(item, column);

            if (data != null)
            {
                ret = (bool)data;
            }

            return ret;
        }

        private bool GetListItemBool(SPListItem item, Guid column)
        {
            bool ret = false;
            object data = GetListItemData(item, column);

            if (data != null)
            {
                ret = (bool)data;
            }

            return ret;
        }

        private object GetListItemData(SPListItem item, string column)
        {
            object ret;

            try
            {
                ret = item[column];
            }
            catch(Exception ex)
            {
                Logger.LogWarning("GetListItemData(): problem when accessing column " + column);
                Logger.LogException(ex);
                throw;
            }

            return ret;
        }

        private object GetListItemData(SPListItem item, Guid column)
        {
            object ret;

            try
            {
                ret = item[column];
            }
            catch (Exception ex)
            {
                Logger.LogWarning("GetListItemData(): problem when accessing column " + column);
                Logger.LogException(ex);
                throw;
            }

            return ret;
        }
    }
}
